package ie.dkit.java3Demulation.gui;

import ie.dkit.java3Demulation.objects.Circle;
import ie.dkit.java3Demulation.objects.Ellipse;
import ie.dkit.java3Demulation.objects.GraphicsObject;
import ie.dkit.java3Demulation.objects.Line;
import ie.dkit.java3Demulation.objects.Point;
import ie.dkit.java3Demulation.objects3d.Circle3D;
import ie.dkit.java3Demulation.objects3d.Line3D;
import ie.dkit.java3Demulation.objects3d.Parallelogram;
import ie.dkit.java3Demulation.objects3d.Point3D;
import ie.dkit.java3Demulation.objects3d.Pyramide;
import ie.dkit.java3Demulation.objects3d.Quader;
import ie.dkit.java3Demulation.objects3d.Rectangle;
import ie.dkit.java3Demulation.objects3d.Sphere;
import ie.dkit.java3Demulation.transforming.Transformable;

import java.awt.BorderLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.ItemEvent;
import java.awt.event.ItemListener;
import java.beans.IntrospectionException;

import javax.swing.BoxLayout;
import javax.swing.JButton;
import javax.swing.JCheckBox;
import javax.swing.JDialog;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTable;
import javax.swing.ListSelectionModel;
import javax.swing.event.TableModelEvent;
import javax.swing.event.TableModelListener;

public class ControlPanel extends JPanel {

	private class GraphicsObjectsTableListener implements ActionListener,
			TableModelListener {

		private GraphicsObjectTableModel graphicsObjectTableModel;

		public GraphicsObjectsTableListener(
				GraphicsObjectTableModel graphicsObjectTableModel) {
			this.graphicsObjectTableModel = graphicsObjectTableModel;
			this.graphicsObjectTableModel.addTableModelListener(this);
		}

		public void actionPerformed(ActionEvent e) {
			final JDialog jDialog = new JDialog(m_GUI,
					"Graphics Objects Editor", false);
			jDialog.setLayout(new BorderLayout());
			final JTable jTable = new JTable(graphicsObjectTableModel);
			jTable.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
			jDialog.add(new JScrollPane(jTable), BorderLayout.CENTER);
			JPanel buttonsPanel = new JPanel();
			JButton copyButton = new JButton("Copy");
			copyButton.addActionListener(new ActionListener() {
				public void actionPerformed(ActionEvent e) {
					m_GUI.copyPaste = graphicsObjectTableModel
							.getGraphicsObjectAt(jTable.getSelectedRow());
				}
			});
			buttonsPanel.add(copyButton);
			JButton editButton = new JButton("Edit");
			editButton.addActionListener(new ActionListener() {
				public void actionPerformed(ActionEvent e) {
					try {
						new PropertyChanger(m_GUI, graphicsObjectTableModel
								.getGraphicsObjectAt(jTable.getSelectedRow()));
					} catch (IntrospectionException e1) {
						JOptionPane.showMessageDialog(m_GUI,
								"IntrospectionException", "Fehler",
								JOptionPane.ERROR);
						e1.printStackTrace();
					}
				}
			});
			buttonsPanel.add(editButton);
			JButton deleteButton = new JButton("Delete");
			deleteButton.addActionListener(new ActionListener() {
				public void actionPerformed(ActionEvent e) {
					GraphicsObject graphicsObject = graphicsObjectTableModel
							.getGraphicsObjectAt(jTable.getSelectedRow());
					if (JOptionPane.showConfirmDialog(m_GUI,
							"Are you sure you want to delete this Object: "
									+ graphicsObject.getName(), "Deletion",
							JOptionPane.YES_NO_OPTION) == JOptionPane.YES_OPTION) {
						m_GUI.removeGraphics(graphicsObject);
					}
				}
			});
			buttonsPanel.add(deleteButton);
			JButton controllButton = new JButton("Controll");
			controllButton.addActionListener(new ActionListener() {
				public void actionPerformed(ActionEvent e) {
					GraphicsObject graphicsObject = graphicsObjectTableModel
							.getGraphicsObjectAt(jTable.getSelectedRow());
					if (graphicsObject instanceof Transformable) {
						Transformable transformable = (Transformable) graphicsObject;
						new ControllButtonDialog(transformable);
					} else {
						JOptionPane.showMessageDialog(m_GUI,
								"Not Controllable", "Error",
								JOptionPane.ERROR_MESSAGE);
					}
				}
			});
			buttonsPanel.add(controllButton);
			jDialog.add(buttonsPanel, BorderLayout.SOUTH);
			jDialog.pack();
			jDialog.setVisible(true);
		}

		public void tableChanged(TableModelEvent e) {
			if (e.getType() == TableModelEvent.UPDATE) {
				int row = e.getFirstRow();
				int column = e.getColumn();
				String name = (String) graphicsObjectTableModel.getValueAt(row,
						column);
				graphicsObjectTableModel.getGraphicsObjectAt(row).setName(name);
			}
		}
	}

	/**
	 * 
	 */
	private static final long serialVersionUID = -628324937211935836L;

	private JButton graphicsObjectsButton;

	private JButton addGraphicsObject;

	private JButton showControlls;

	private JCheckBox showCoordinateSystem;

	private JCheckBox perspective;

	private GUI m_GUI;

	// TODO: add all necessary Object
	private Object[] possibleGraphicsObjects = { Point.class, Line.class,
			Circle.class, Point3D.class, Line3D.class, Rectangle.class,
			Parallelogram.class, Pyramide.class, Quader.class, Ellipse.class,
			Circle3D.class, Sphere.class };

	public ControlPanel(GUI gui) {
		this.m_GUI = gui;
		setLayout(new BoxLayout(this, BoxLayout.Y_AXIS));
		add(graphicsObjectsButton = new JButton("View Graphics"));
		graphicsObjectsButton
				.addActionListener(new GraphicsObjectsTableListener(
						m_GUI.graphicsObjectTableModel));
		add(addGraphicsObject = new JButton("Add Graphics"));
		addGraphicsObject.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent e) {
				Object selectedValue = JOptionPane.showInputDialog(null,
						"Choose one", "Input", JOptionPane.INFORMATION_MESSAGE,
						null, possibleGraphicsObjects,
						possibleGraphicsObjects[0]);
				if (selectedValue == null) {
					return;
				}
				try {
					Object newObject = ((Class<?>) selectedValue).newInstance();
					if (newObject instanceof GraphicsObject) {
						GraphicsObject graphicsObject = (GraphicsObject) newObject;
						graphicsObject
								.setName(JOptionPane
										.showInputDialog("Please Type in the name for the new Object"));
						m_GUI.addGraphics(graphicsObject);
						try {
							new PropertyChanger(m_GUI, graphicsObject);
						} catch (IntrospectionException e1) {
							JOptionPane.showMessageDialog(m_GUI,
									"Wasn't able to open PropertyChanger");
							e1.printStackTrace();
						}
					} else {
						System.err
								.println("Please check the list of Possible Graphic Objects in "
										+ this.getClass().getSimpleName());
						System.exit(1);
					}
				} catch (InstantiationException e1) {
					System.err
							.println("Please check the list of Possible Graphic Objects in "
									+ this.getClass().getSimpleName());
					e1.printStackTrace();
					System.exit(1);
				} catch (IllegalAccessException e1) {
					System.err
							.println("Please check the list of Possible Graphic Objects in "
									+ this.getClass().getSimpleName());
					e1.printStackTrace();
					System.exit(1);
				}
			}
		});
		add(showControlls = new JButton("Show Controlls"));
		showControlls.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent e) {
				new ControllButtonDialog("Main Controller",
						m_GUI.transformables);
			}
		});
		add(showCoordinateSystem = new JCheckBox("CoordinateSys"));
		showCoordinateSystem.addItemListener(new ItemListener() {
			public void itemStateChanged(ItemEvent e) {
				if (((JCheckBox) e.getSource()).isSelected()) {
					m_GUI.showCoordinateSystem();
				} else {
					m_GUI.hideCoordinateSystem();
				}
			}
		});
		add(perspective = new JCheckBox("Perspective"));
		perspective.addItemListener(new ItemListener() {
			public void itemStateChanged(ItemEvent e) {
				m_GUI.m_DisplayCanvas
						.setPerspective(((JCheckBox) e.getSource())
								.isSelected());
			}
		});
	}
}
